import jwtDecode from 'jwt-decode'
import userService from '@/service/userService'

import conversationService from '@/service/conversationService'

const data = {
  // 同步队列
  syncQueue: new Set(),

  // 是否正在处理队列
  isProcessing: false,

  // 当前用户
  currentUser: {},

  // popup是否打开
  isPopupOpen: false,
}

/**
 * 提供给内部使用的方法
 */
const methods = {
  /**
   * 添加到队列
   * @param userId
   * @param conversations
   */
  addToQueue(conversations) {
    conversations.forEach(conversationId => {
      data.syncQueue.add(conversationId)
    })

    // 如果队列中有数据，并且当前没有在处理队列，则开始处理队列
    if (data.syncQueue.size > 0 && !data.isProcessing) {
      this.processQueue()
    }
  },

  /**
   * 处理队列
   * @returns {Promise<void>}
   */
  async processQueue() {
    // 设置状态标记
    data.isProcessing = true

    // 获取第一个元素
    const id = [...data.syncQueue][0]
    this.sendQueueStatus()

    try {
      const detail = await conversationService.fetchApiDetail(id)
      await conversationService.updateMapping(id, detail)
    } catch (e) {
      // 出错时，重置队列
      this.resetQueue()
    }

    // 处理完毕，从队列中删除
    data.syncQueue.delete(id)

    // 如果队列已处理完，重置队列状态
    if (data.syncQueue.size === 0) {
      this.resetQueue()
    } else {
      // 模拟网络延迟, 避免Too many requests in 1 minute. Try again later.
      // eslint-disable-next-line no-promise-executor-return
      await new Promise(resolve => setTimeout(resolve, 800 + Math.random() * 1200))
      this.processQueue()
    }
  },

  /**
   * 发送队列状态
   */
  sendQueueStatus() {
    if (data.isPopupOpen) {
      chrome.runtime.sendMessage({
        action: 'updateQueueStatus',
        target: 'popup',
        params: {
          queueSize: data.syncQueue.size,
          isProcessing: data.isProcessing,
        },
      })
    }
  },

  /**
   * 重置队列
   */
  resetQueue() {
    data.syncQueue.clear()
    data.isProcessing = false
    this.sendQueueStatus()
  },

  /**
   * 保存用户信息
   * @param chatGptToken
   */
  saveUserByToken(chatGptToken) {
    // 截取chatGptToken.value中Bearer后面的token
    const decoded = jwtDecode(chatGptToken.split(' ')[1])

    // 获取https://api.openai.com/auth中的user_id
    const userId = decoded?.['https://api.openai.com/auth']?.user_id
    const email = decoded?.['https://api.openai.com/profile']?.email

    if (!userId) {
      return
    }

    // 切换用户
    if (userId !== data.currentUser.id) {
      // 重置队列
      this.resetQueue()
    }

    data.currentUser = {
      id: userId,
      email,
    }
    userService.saveUser(data.currentUser)
    chrome.storage.local.set({ chatGptToken })
  },
}

/**
 * 提供给监听器的方法
 */
const actions = {
  /**
   * 添加到队列
   * @param sendResponse
   * @param params
   */
  addToQueue(sendResponse, params) {
    methods.addToQueue(params.conversationIds)
  },
}

chrome.runtime.onMessage.addListener(
  (request, sendResponse) => {
    const { action, target } = request
    const params = request.params ?? {}

    if (target !== 'background' || !actions[action]) {
      return
    }

    // 调用methods中的action方法
    actions[action](sendResponse, params)
  },
)

chrome.runtime.onConnect.addListener(port => {
  if (port.name === 'popup') {
    data.isPopupOpen = true

    port.onDisconnect.addListener(() => {
      data.isPopupOpen = false
    })
  }
})

chrome.webRequest.onBeforeSendHeaders.addListener(
  details => {
    const {
      url, method, requestHeaders, initiator,
    } = details

    // 从requestHeaders获取name为Authorization的值
    const chatGptToken = requestHeaders.find(item => item.name === 'Authorization')

    // 将token存入chrome.storage.local
    if (chatGptToken && chatGptToken.value) {
      methods.saveUserByToken(chatGptToken.value)
    } else {
      // 如果没有token, 那么拦截请求没有意义，直接返回
      return
    }

    // 如果details.initiator是chrome-extension://，那么说明是从插件发起的请求，不需要拦截
    if (initiator.startsWith('chrome-extension://')) {
      return
    }

    if (url.startsWith('https://chat.openai.com/backend-api/conversation/') && method === 'GET') {
      // 截取对话id
      // const conversationId = url.split('/').pop()
      // console.log('conversationId:', conversationId)
    } else if (url.startsWith('https://chat.openai.com/backend-api/moderations') && method === 'POST') {
      // 通知监听器，现在发送会话

    } else if (url.startsWith('https://chat.openai.com/backend-api/conversations') && method === 'GET') {
      // 获取对话列表
      conversationService.incrementalUpdateList().then(res => {
        if (res && res.conversationIds) {
          methods.addToQueue(res.conversationIds)
        }
      })
    } else if (url.startsWith('https://chat.openai.com/backend-api/conversation/') && method === 'PATCH') {
      // 更改对话标题或删除对话
      // 截取对话id
      const conversationId = url.split('/').pop()

      conversationService.delete(conversationId)
    }
  },
  {
    urls: [
      'https://chat.openai.com/backend-api/conversation/*',
      'https://chat.openai.com/backend-api/moderations',
      'https://chat.openai.com/backend-api/conversations*',
      'https://chat.openai.com/backend-api/conversation/gen_title/*',

      // '<all_urls>',
    ],
  },
  ['requestHeaders'],
)
